<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\ResponseException;
use App\Jobs\AutoClearOrder;
use App\Models\Goods;
use App\Models\GoodsSku;
use App\Models\Order;
use App\Models\OrderInfo;
use App\Models\SpecValue;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;
use Whoops\Exception\ErrorException;

class OrderController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $order_status = $request->input('order_status');

        $where = [
            'user_id'=>auth('api')->id()
        ];
        if($order_status == '0'){
            $where['status'] = '0';
        }else if($order_status == 4){
            $where = [
                'user_id'=>auth('api')->id(),
                ['status','>=',4]
            ];
        }else if($order_status && $order_status != 'all'){
            $where['status'] = $order_status;
        }

        //查询用户的订单
        $orderList = Order::query()->select('id','order_sn','order_type','status','express_price','goods_total','price_total','created_at')
            ->where($where)
            ->orderBy('created_at','desc')
            ->paginate(10);

        foreach ($orderList as $k => $v){
            $order_info = OrderInfo::query()
                    ->select('order_id','order_sn','goods_id','goods_name','thumb','sku_list','number','price')
                    ->where([
                        'order_id'=>$v['id'],
                        'order_sn'=>$v['order_sn']
                    ])->get()->toArray();

            foreach ($order_info as $k1 => $goods) {
                $sku_ids = explode(',',$goods['sku_list']);

                $goods_spec = SpecValue::query()
                            ->select('spec.spec_name','value')
                            ->leftJoin('spec','spec_value.spec_id','=','spec.id')
                            ->whereIn('spec_value.id',$sku_ids)
                            ->get()->toArray();

                $order_info[$k1]['sku_info'] = $goods_spec;

            }

            $orderList[$k]['order_info'] = $order_info;
        }

        throw new ResponseException(200,'ok',$orderList);
    }


    /**
     * 订单详情
     * User: ihome
     * @param Request $request
     */
    public function show(Request $request)
    {
        $order_sn = $request->input('order_sn');

        if(!$order_sn){
            throw new ResponseException(404,'没有找到该订单');
        }

        $order = Order::query()
            ->select('order.id','order_sn','order_type','status','express_price','goods_total','price_total','created_at',
                    'pay_time','send_time','confirm_time','comment_time','after_serve_time',
                    'order.county_id','address','username','tel','order.remark',
                \DB::raw('REPLACE(my_region.whole_name,",","") as area'),
                'org_price_total','coupon_price'
            )
            ->leftJoin('region','region.county_id','=','order.county_id')
            ->where([
                'user_id'=>auth('api')->id(),
                'order_sn'=>$order_sn,
        ])->first();

        if(!$order){
            throw new ResponseException(404,'没有找到该类订单');
        }

        $order_info = $order->orderInfo()->select(
                'order_id','order_sn','goods_id','goods_name','thumb','sku_list','number','price'
            )->get()->toArray();

        foreach ($order_info as $k => $v) {
            $sku_arr = explode(',',$v['sku_list']);

            $sku_info = SpecValue::query()
                        ->select('spec.spec_name','value')
                        ->leftJoin('spec','spec.id','=','spec_value.spec_id')
                        ->whereIn('spec_value.id',$sku_arr)
                        ->get()->toArray();

            $order_info[$k]['sku_info'] = $sku_info;
        }

        $order['order_info'] = $order_info;

        throw new ResponseException(200,'ok',$order);
    }

    /**
     * 订单删除
     * User: ihome
     * @param Request $request
     * @throws ResponseException
     */
    public function destroy(Request $request)
    {
        $order_sn = $request->input('order_sn');

        if(!$order_sn){
            throw new ResponseException(404,'没有找到该订单');
        }

        $order = Order::query()->where([
                'user_id'=>auth('api')->id(),
                'order_sn'=>$order_sn,
                'status'=>'0'
            ])->first();

        if(!$order){
            throw new ResponseException(404,'没有找到该类订单');
        }

        if($order->order_type == 2){
        	throw new ResponseException(400,'秒杀订单不能删除');
        }

        //先删order_info
        $order->orderInfo()->delete();
        $order->delete();

        throw new ResponseException(200,'删除成功');
    }


    /**
     * 立即下单
     * User: Clannad ~ ☆
     * Date: 2020/3/13 0013 10:49
     */
    public function buyGoods(Request $request)
    {
        $goods_id = $request->input('goods_id');
        $sku_list = $request->input('sku_list');
        $goods_num = $request->input('goods_num');

        //判断商品是否存在
        $goods = Goods::query()
                    ->select('goods_name','thumb','id')
                    ->where([
                    'id'=>$goods_id,
                    'status'=>1
                ])->first();

        if(!$goods){
            throw new ResponseException(404,'商品不存在');
        }

        $goods['number'] = $goods_num;

        //判断库存是否足
        $sku = GoodsSku::query()->where([
                'goods_id'=>$goods_id,
                'sku_list'=>$sku_list
            ])->first();

        if(!$sku){
            throw new ResponseException(400,'商品规格不存在');
        }

        if($goods_num > $sku['inventory']){
            throw new ResponseException(400,'商品信息已过期，请重新刷新页面');
        }

        $goods['price'] = $sku['price'];

        //获得sku_info
        $goods['sku_info'] = SpecValue::query()
                            ->select('spec.spec_name','spec_value.value')
                            ->leftJoin('spec','spec_value.spec_id','=','spec.id')
                            ->whereIn('spec_value.id',explode(',',$sku_list))
                            ->get()->toArray();
        //查询收货地址
        $user_address = auth('api')->user()->user_address()
            ->select('user_address.id', 'user_id', 'username', 'tel', 'user_address.county_id',
                \DB::raw('REPLACE(my_region.whole_name,",","") as area'),
                'address', 'default')
            ->leftJoin('region','user_address.county_id','=','region.county_id')
            ->groupBy(['user_address.id'])
            ->orderBy('default','desc')
            ->get()->toArray();

        $data = [
            'cart_list'    => [$goods],
            'user_address' => $user_address
        ];

        throw new ResponseException(200,'ok',$data);

    }


    /**
     * 创建订单
     * User: Clannad ~ ☆
     * @param Request $request
     */
    public function createOrder(Request $request)
    {
        $goods_id = $request->input('goods_id');
        $sku_list = $request->input('sku_list');
        $goods_num = $request->input('goods_num');
        $user_addr_id = $request->input('user_addr_id');
        $remark = $request->input('remark');
        $express_type = $request->input('express_type');

        //判断商品是否存在
        $goods = Goods::query()
            ->select('goods_name','thumb','id','kill_status')
            ->where([
                'id'=>$goods_id,
                'status'=>1
            ])->lockForUpdate()->first();

        if(!$goods){
            throw new ResponseException(404,'商品不存在');
        }

        //判断用户地址
        $user_address = auth('api')->user()->user_address()->where('id',$user_addr_id)->first();

        if(!$user_address){
            throw new ResponseException(400,'用户地址不存在');
        }

        \DB::beginTransaction();

        try{
            //判断库存是否足
            $sku = GoodsSku::query()->where([
                'goods_id'=>$goods_id,
                'sku_list'=>$sku_list
            ])->lockForUpdate()->first();

            if(!$sku){
                throw new ResponseException(400,'商品规格不存在');
            }

            if($goods_num > $sku['inventory']){
                throw new ResponseException(400,'商品信息已过期，请重新下单');
            }

            $data = [
                'order_sn'=>createUniqueOrderSn(),
                'user_id'=>auth('api')->id(),
                'province_id'=>$user_address['province_id'],
                'city_id'=>$user_address['city_id'],
                'county_id'=>$user_address['county_id'],
                'address'=>$user_address['address'],
                'username'=>$user_address['username'],
                'tel'=>$user_address['tel'],
                'remark'=>$remark,
                'express_type'=>$express_type,
                'express_price'=>$express_type == 1 ? 8 : 0,
                'goods_total'=>$goods_num,
            ];

            $org_price_total = $goods_num * $sku['price'];
            $data['org_price_total'] = $org_price_total;
            $data['price_total'] = $org_price_total + $data['express_price']; //订单总额

            $order = Order::create($data);

            if($order->id){
                $order_info = [
                    'order_id'=>$order['id'],
                    'order_sn'=>$data['order_sn'],
                    'goods_id'=>$goods_id,
                    'goods_name'=>$goods['goods_name'],
                    'thumb'=>$goods['thumb'],
                    'sku_list'=>$sku_list,
                    'number'=>$goods_num,
                    'price'=>$sku['price'],
                ];

                $orderInfoModel = OrderInfo::create($order_info);


                if($orderInfoModel->id){
                    //减库存
                    $sku->decrement('inventory',$order_info['number']);
                    $goods->decrement('inventory',$order_info['number']);

                    //如果商品的秒杀状态是1 那么还要减秒杀hash表的内容
                    if($goods->kill_status == 1){
                        $seckill_id = $goods->seckill_goods()->where(['kill_status'=>1])->value('id');
                        $key = 'goods_sku_stock:goods_id:'.$goods_id.':active_id:'.$seckill_id;

                        $old_inventory = Redis::hget($key,$order_info['sku_list']);

                        $new_inventory = $old_inventory - $order_info['number'];
                        Redis::hset($key,$order_info['sku_list'],$new_inventory);
                    }

                    //派发延时任务，过期不付款自动取消订单
                    AutoClearOrder::dispatch($order_info['order_id'],$order_info['order_sn'])->delay(900);
                    //返回订单号给前端
                    \DB::commit();
                    throw new ResponseException(200,'下单成功',['order_sn'=>$data['order_sn']]);
                }else{
                    \DB::rollBack();
                    throw new ResponseException(500,'下单失败，请联系管理员 -1');
                }
            }else{
                \DB::rollBack();
                throw new ResponseException(500,'下单失败，请联系管理员 -2');
            }
        }catch (ErrorException $e){
            \DB::rollBack();
            \Log::info('下单错误：' . $e->getMessage());
            throw new ResponseException(500,'下单失败，请联系管理员 -3');
        }
    }

    /**
     * 订单支付页面
     * User: ihome
     * @param Request $request
     */
    public function order_pay_page(Request $request)
    {
        $order_sn = $request->input('order_sn');

        if(! $order_sn){
            throw new ResponseException(404,'没有找到该笔订单');
        }

        $order_info = Order::query()->select('order_sn','goods_total','price_total','coupon_price','org_price_total','created_at','express_price')
                    ->where([
                        'order_sn'=>$order_sn,
                        'status'=>0,//未支付的订单
                    ])->first();

        if(!$order_info){
            throw new ResponseException(404,'未找到该订单，或者该订单已经支付，请返回个人中心查看');
        }

        //返回个人余额 用于余额支付
        $user_balance = auth('api')->user()->balance;

        throw new ResponseException(200,'ok',[
            'order_info'=>$order_info->toArray(),
            'balance'=>$user_balance
        ]);
    }
}
